/******************************************************************
 * HttpUtils.java
 * Copyright 2017 by CEIEC Company. All Rights Reserved.
 * CreateDate：2017年5月11日
 * Author：李涛
 * Version：1.0.0
 ******************************************************************/

package com.ceiec.base.common.utilities;

import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;


/**
 * <b>修改记录：</b>
 * <p>
 * <li>
 * <p>
 * ---- 李涛 2017年5月11日
 * </li>
 * </p>
 *
 * <b>类说明：</b>
 * <p>
 * HTTP工具类
 * </p>
 */
public final class HttpUtils {


    private static int TIMEOUT = 30000;



    private static final int BUFFER_SIZE = 1024;


    private static Logger logger = LoggerFactory.getLogger(HttpUtils.class);

    private HttpUtils() {

    }


    /**
     * <b>方法说明：</b>
     * <ul>
     * 以Post方式请求数据(仅用于数据量较大时的传输)
     * </ul>
     *
     * @param requestUrl 请求地址
     * @param json       json格式的请求参数
     * @return String 返回的响应字符串内容
     */
    public static String doPostBigData(String requestUrl, String json) {
        Map<String, String> headerMap = new HashMap<>();
        //设置请求内容类型
        headerMap.put("Content-Type", "application/json;charset=UTF-8");
        return doPostBigData(requestUrl, headerMap, json);
    }

    /**
     * <b>方法说明：</b>
     * <ul>
     * 以Post方式请求数据(仅用于数据量较大时的传输)
     * </ul>
     *
     * @param requestUrl 请求地址
     * @param headerMap  头部参数map
     * @param json       json格式的请求参数
     * @return String 返回的响应字符串内容
     */
    public static synchronized String doPostBigData(String requestUrl, Map<String, String> headerMap, String json) {
        //计时
        StopWatch timer = new StopWatch();
        timer.start();

        ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
        HttpURLConnection httpURLConnection = null;
        OutputStream out = null;
        BufferedInputStream in = null;
        String response = null;

        try {
            URL url = new URL(requestUrl);

            httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setDoInput(true);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setConnectTimeout(TIMEOUT);
            httpURLConnection.setReadTimeout(TIMEOUT);

            //追加header参数
            if (CollectionUtils.isEmpty(headerMap)) {
                for (String strKey : headerMap.keySet()) {
                    httpURLConnection.setRequestProperty(strKey, headerMap.get(strKey));
                }
            }
            httpURLConnection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            //连接,发送请求
            httpURLConnection.connect();
            out = httpURLConnection.getOutputStream();
            if (json != null) {
                out.write(json.getBytes("utf-8"));
            }
            out.flush();

            //接收响应
            try {
                in = new BufferedInputStream(httpURLConnection.getInputStream());
            } catch (IOException e) {
                in = new BufferedInputStream(httpURLConnection.getErrorStream());
            }

            byte[] buf = new byte[BUFFER_SIZE];
            int l = 0;
            while ((l = in.read(buf)) != -1) {
                byteArrayOut.write(buf, 0, l);
            }
            byte[] bytes = byteArrayOut.toByteArray();
            response = new String(bytes, "utf-8");

            return response;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            timer.stop();

            logger.info("doPostBigData.headerMap:{}, requestUrl:{}, param:{},\n response:{},took {} ms", headerMap, requestUrl, json, response, timer.getTime());

            close(byteArrayOut);
            close(in);
            close(out);
            close(httpURLConnection);
        }
    }

    /**
     * <b>方法说明：</b>
     * <ul>
     * 关闭流
     * </ul>
     *
     * @param stream 流
     */
    private static void close(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
                stream = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * <b>方法说明：</b>
     * <ul>
     * 关闭Http连接
     * </ul>
     *
     * @param httpConn http连接
     */
    private static void close(HttpURLConnection httpConn) {
        if (httpConn != null) {
            httpConn.disconnect();
        }
    }


}
